定义
将请求封装成一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或者请求日志,以及支持可撤销的操作。
场景
去饭馆吃饭,客人作为发起者点菜,厨师作为执行者做菜。但为了提高效率,分开职责,增加服务员的角色,服务员负责和客人与厨师交互,记录点菜,传达信息。
UML
示例代码
//厨师接收消息 做菜
public class Receiver {
public void execute() {
System.out.println("Execute command");
}
}
// 服务员管理收到的各类别的命令,通知厨师去做,所以需要维持一个厨师的引用
//这里做了简化,其实服务员还可以单独做一个类,创建一个list保存各式各样的command
abstract class Command {
protected Receiver receiver;
public Command(Receiver receiver) {
this.receiver = receiver;
}
abstract public void execute();
}
public class ConcreteCommand extends Command {
public ConcreteCommand(Receiver receiver) {
super(receiver);
}
@Override
public void execute() {
receiver.execute();
}
}
//客户去点菜,所以需要服务员的引用
public class Invoker {
private Command cmd;
public void setCommand(Command cmd) {
this.cmd = cmd;
}
public void executeCommand() {
cmd.execute();
}
}
//客户代码
public class main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Receiver r = new Receiver();
Command c = new ConcreteCommand(r);
Invoker i = new Invoker();
i.setCommand(c);
i.executeCommand();
}
}
评价
优点
- 能较容易地设计一个命令队列
- 容易把命令记入日志
- 允许接收请求的一方决定是否要否决请求
- 容易实现对请求的撤销和重做
- 易于拓展命令类
- 把请求一个操作的对象与执行一个操作的对象分割开